﻿using NUnit.Framework;
using EventHandler.Libraries.Business.Security;
using System;
using EventHandler.Libraries.Business.Database;
using Rhino.Mocks;
using System.Data;

namespace EventHandler.Libraries.Business.Tests.Security.AccountTests
{
	[TestFixture]
	public class RetrieveAccountTests
	{
		private IAccount RetrieveAccount(string userName)
		{
			IAccount account = null;

			IDatabaseHelper dbHelper = AccountTestUtilities.CreateDatabaseHelper();
			IAccountHelper helper = new AccountHelper(dbHelper);

			var cnn = MockRepository.GenerateMock<IDbConnection>();
			dbHelper.Expect(x => dbHelper.GetConnection()).Return(cnn);

			var cmd = MockUtilities.CreateMockCommand(cnn);
			var paramAccountId = MockUtilities.CreateMockParameter(cmd);

			var dr = MockRepository.GenerateMock<IDataReader>();
			cmd.Expect(x => x.ExecuteReader()).Return(dr);
			dr.Expect(x => x.Read()).Return(true);
			
			//TODO: Populate the data reader with mock data to be returned.

			helper.RetrieveAccount(userName);

			cnn.AssertWasCalled(x => x.Open());
			cnn.AssertWasCalled(x => x.Close());
			cmd.AssertWasCalled(x => x.ExecuteNonQuery());
			dr.AssertWasCalled(x => x.Read());
			
			Assert.AreEqual("Auth.GetUserByUserName", cmd.CommandText);
			Assert.AreEqual(CommandType.StoredProcedure, cmd.CommandType);

			Assert.AreEqual("@UserName", paramAccountId.ParameterName);
			Assert.AreEqual(userName, paramAccountId.Value);
			Assert.AreEqual(255, paramAccountId.Size);
			Assert.AreEqual(DbType.String, paramAccountId.DbType);

			return account;
		}

		[Test]
		[Ignore("Test Not Ready")]
		public void RetrieveAccount_Should_Succeed_If_UserName_Exists()
		{
			IAccount result = RetrieveAccount("RealUserName");
			Assert.IsNotNull(result);
		}

		[Test]
		[Ignore("Test Not Ready")]
		public void RetrieveAccount_Should_Return_Null_If_UserName_Does_Not_Exist()
		{
			IAccount result = RetrieveAccount("NotARealUser");
			Assert.IsNull(result);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void RetrieveAccount_Should_Fail_If_UserName_Is_Null()
		{
			RetrieveAccount(null);
		}

		[Test]
		[ExpectedException(typeof(ArgumentException))]
		public void RetrieveAccount_Should_Fail_If_UserName_Is_Empty_String()
		{
			RetrieveAccount(string.Empty);
		}
	}
}
